/**
 * @file switch_driver.h
 * @brief get switch status
 *       - for default switches: A0-A1-A2, A0 is default state
 * @author    - Adela 
 *            - Robert Zhang <armner@gmail.com>
 *            - 
 */
#include "switch_driver.h"
#include "stm32f2xx.h"


#define BITGPIOA(x) (PIN_##x&GPIOA->IDR)
#define BITGPIOB(x) (PIN_##x&GPIOB->IDR)
#define BITGPIOC(x) (PIN_##x&GPIOC->IDR)
#define BITGPIOE(x) (PIN_##x&GPIOE->IDR)

#define PIN_SW_F    GPIO_Pin_14    ///< PE.14
#define PIN_SW_E_H GPIO_Pin_4    ///< PB.03
#define PIN_SW_E_L GPIO_Pin_3    ///< PB.04
#define PIN_SW_A_L GPIO_Pin_5    ///< PB.05
#define PIN_SW_A_H GPIO_Pin_0    ///< PE.00
#define PIN_SW_B_L GPIO_Pin_1    ///< PE.01
#define PIN_SW_B_H GPIO_Pin_2    ///< PE.02
#define PIN_SW_C_L GPIO_Pin_15  ///< PE.15
#define PIN_SW_C_H GPIO_Pin_5   ///< PA.05
#define PIN_SW_D_L GPIO_Pin_7   ///< PE.07
#define PIN_SW_D_H GPIO_Pin_1  ///< PB.01
#define PIN_SW_G_L GPIO_Pin_9  ///< PE.09
#define PIN_SW_G_H GPIO_Pin_8 ///< PE.08
#define PIN_SW_H GPIO_Pin_13   ///< PE.13

#define SW_F (!BITGPIOE(SW_F))
#define SW_E_H (!BITGPIOB(SW_E_H))
#define SW_E_L (!BITGPIOB(SW_E_L))
#define SW_A_L (!BITGPIOB(SW_A_L))
#define SW_A_H (!BITGPIOE(SW_A_H))
#define SW_B_L (!BITGPIOE(SW_B_L))
#define SW_B_H (!BITGPIOE(SW_B_H))
#define SW_C_L (!BITGPIOE(SW_C_L))
#define SW_C_H (!BITGPIOA(SW_C_H))
#define SW_D_L (!BITGPIOE(SW_D_L))
#define SW_D_H (!BITGPIOB(SW_D_H))
#define SW_G_L (!BITGPIOE(SW_G_L))
#define SW_G_H (!BITGPIOE(SW_G_H))
#define SW_H (!BITGPIOE(SW_H))

int switch_open(Driver *driver)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOAEN, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOBEN, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOEEN, ENABLE);

    /// PA: 1
    GPIO_InitStructure.GPIO_Pin =PIN_SW_C_H;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /// PB:4
    GPIO_InitStructure.GPIO_Pin =PIN_SW_E_H | PIN_SW_E_L | PIN_SW_A_L | PIN_SW_D_H;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /// PE: 9
    GPIO_InitStructure.GPIO_Pin =PIN_SW_F | PIN_SW_A_H | PIN_SW_B_L | PIN_SW_B_H | PIN_SW_C_L | PIN_SW_D_L | PIN_SW_G_L | PIN_SW_G_H | PIN_SW_H;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    
    GPIO_Init(GPIOE, &GPIO_InitStructure);

    return 0;
}

int switch_write(Driver *driver, void *buffer, int len, OFFSET offset)
{
    return 0;
}

int switch_read(Driver *driver, void *buffer, int len, OFFSET offset)
{
    int t_int;
    char *p_char;

    if(len >22) len =22;

    p_char =(char*)buffer;
    for(t_int =0; t_int<len; t_int++)
    {
        switch(t_int)
        {
        case 0: *p_char++ =SW_A_H? 1:0; break;
        case 1: *p_char++ =(SW_A_H|SW_A_L)? 0:1; break;
        case 2: *p_char++ =SW_A_L? 1:0; break;
        case 3: *p_char++ =SW_B_H? 1:0; break;
        case 4: *p_char++ =(SW_B_H|SW_B_L)? 0:1; break;
        case 5: *p_char++ =SW_B_L? 1:0; break;
        case 6: *p_char++ =SW_C_H? 1:0; break;
        case 7: *p_char++ =(SW_C_L|SW_C_H)? 0:1; break;
        case 8: *p_char++ =SW_C_L? 1:0; break;
        case 9: *p_char++ =SW_D_H? 1:0; break;
        case 10: *p_char++ =(SW_D_L|SW_D_H)? 0:1; break;
        case 11: *p_char++ =SW_D_L? 1:0; break;
        case 12: *p_char++ =SW_E_H? 1:0; break;
        case 13: *p_char++ =(SW_E_L|SW_E_H)? 0:1; break;
        case 14: *p_char++ =SW_E_L? 1:0; break;
        case 15: *p_char++ =SW_G_H? 1:0; break;
        case 16: *p_char++ =(SW_G_L|SW_G_H)? 0:1; break;
        case 17: *p_char++ =SW_G_L? 1:0; break;
        case 18: *p_char++ =SW_F? 0:1; break;
        case 19: *p_char++ =SW_F? 1:0; break;
        case 20: *p_char++ =SW_H? 0:1; break;
        case 21: *p_char++ =SW_H? 1:0; break;
        }
    }

    return t_int;
}

int switch_io_control(Driver *driver, int io_type, int data)
{

    return 0;
}

int switch_close(Driver *driver)
{
    return 0;
}




Driver switch_driver=
{
    &switch_open,
    &switch_write,
    &switch_read,
    &switch_io_control,
    &switch_close
};

